﻿using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Domain.Infrastructure;

namespace Application.Infrastructure
{



    //public class QueryParameters
    //{  
    //    public string order { get; set; }
    //    public int page { get; set; }
    //    public int rows { get; set; }
    //    public string sort { get; set; }
    //}

    /// <summary>
    /// 分页帮助类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public static class PagingHelper<T>
    {
        public static List<T> Query(IEnumerable<T> queryable, Pagination queryParameters)
        {
            if (queryable == null)
            {
                return new List<T>();
            }
            queryParameters = queryParameters ?? new Pagination();
            IQueryable<T> source = queryable.AsQueryable();

            var page = queryParameters.Page;
            var rows = queryParameters.Rows;
            var sort = queryParameters.Sort;
            var order = queryParameters.Order;

            queryParameters.Records = source.Count();

            int count = (page - 1) * rows;

            IQueryable<T> s = source;

            if (!string.IsNullOrWhiteSpace(sort))
            {
                var sortExpression = Expression.Parameter(source.ElementType);
                var selector = Expression.Lambda(Expression.PropertyOrField(sortExpression, sort), sortExpression);
                if (order.ToLower() == "asc")
                {
                    s = (IQueryable<T>)source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "OrderBy", new[] { source.ElementType, selector.Body.Type }, source.Expression, selector));
                }
                else if (order.ToLower() == "desc")
                {
                    s = (IQueryable<T>)source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "OrderByDescending", new[] { source.ElementType, selector.Body.Type }, source.Expression, selector));
                }
            }

            //方法1
            s = count == 0 ? s.Take(rows) : s.Skip(count).Take(rows);
            //方法2
            // s = count == 0 ? Queryable.Take<T>(s, rows) : Queryable.Take<T>(Queryable.Skip<T>(s, count), rows);

            //return n 
            return s.ToList();
        }
    }

}
